springboot 从jar包中分离出lib包实现lib包与项目代码分离 您所在的位置:网站首页 maven 打jar包没有lib springboot 从jar包中分离出lib包实现lib包与项目代码分离

springboot 从jar包中分离出lib包实现lib包与项目代码分离

2023-06-20 20:15| 来源: 网络整理| 查看: 265

问题背景:服务依赖的.jar包文件会和代码打包在一起,会导致最终打包好的文件特别大,部署的时候每次都需要上传大文件很麻烦

为了解决这个问题,需要将打包文件里面的lib包文件和classes文件分离开。

当前解决方案

在springboot 项目中,为了方便jar包替换,把 jar 包中 BOOT-INF\lib 下面的 .jar 文件拷贝出来放在外部文件中

 使用 java -jar 的方式启动jar 包时,出现了如下异常:

F:\TbpsServer>C:/Java/jdk1.8.0_251/bin/java -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:NewRatio=3 -Dhostname=tbps01 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9110 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.ext.dirs=C:/Java/jdk1.8.0_251/jre/lib/ext;./lib -jar tbps.jar Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128M; support was removed in 8.0 Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0 Logging system failed to initialize using configuration from 'null' java.lang.IllegalStateException: Logback configuration error detected: ERROR in ch.qos.logback.core.pattern.parser.Compiler@32c4e8b2 - Failed to instantiate converter class [com.cfcc.tbps.util.LogDesensitizationUtil] for keyword [msg] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type com.cfcc.tbps.util.LogDesensitizationUtil

 注意: 抛出一个logback 异常,项目中为了做日志脱敏, 自定义一个 logback 的 MessageConverter

 自定义类实现:

package util; import ch.qos.logback.classic.pattern.MessageConverter; import ch.qos.logback.classic.spi.ILoggingEvent; public class LogDesensitizationUtil extends MessageConverter { @Override public String convert(ILoggingEvent event) { String oriLog = event.getFormattedMessage(); return filterSensitive(oriLog); } private String filterSensitive(String oriLog){ String sensString = ""; if(oriLog.contains("")){ String payAcct = oriLog.substring(oriLog.indexOf("")+9,oriLog.indexOf("")); for (int i=0;i ${log.pattern} ${log.path}/%d{yyyyMMdd}/TbpsServer.log.%i 100MB INFO ACCEPT ACCEPT

启动命令

title TEST cd .. rem 设置java环境变量 set JAVA_HOME=C:/Java/jdk1.8.0_251 set JAVA_JRE=%JAVA_HOME%/jre/lib/ext rem 设置java虚拟机参数信息 set JAVA_OPPTIONS=-Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:NewRatio=3 -Dhostname=tbps01 rem 开启jconsole系统监测 set JCONSOLE=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9110 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false rem 加载外部jar包 set JAVA_EXT=-Djava.ext.dirs=%JAVA_JRE%;./lib %JAVA_HOME%/bin/java %JAVA_OPPTIONS% %JCONSOLE% %JAVA_EXT% -jar tbps.jar

springboot 类加载过程

Springboot 的类加载过程是AppClassLoader加载org目录下的所有类文件,再由JarLauncher创建LauncherClassLoader(父类加载器是APPClassLoader)作为默认的类加载器去加载BOOT/classes/ 和BOOT-INF/lib/中的类和第三方库,并运行start-class中的main方法启动springboot应用。

 

问题分析:

因为通过 -Djava.ext.dirs  方式指定引导类加载器的路径,这时第三方包(包括Logback )会被引导类加载器加载,BOOT-INF\class 下的类(项目类)会被 LauncherClassLoader类加载器加载。这时,在Spring 解析的logback-spring.xml 文件,创建LogDesensitizationUtil对象时,会导致父类加载器加载的类调用子类加载器加载的类,因为父类加载器加载的类不能调用子类加载器加载的类,会导致对象初始化异常。

解决方案:

将logback 转换器的自定义实现类打成jar包,放到lib目录下,和第三方包一起被Extension ClassLoader 加载,问题解决。

 

 

通过参考网上资料:【Maven】Maven打jar包分离lib包_maven打包lib分离_你怎么不笑了的博客-CSDN博客 

 Maven打包分离lib包

步骤一: 先修改pom.xml文件,打包的时候将lib和classes分离

org.apache.maven.plugins maven-dependency-plugin copy-dependencies package copy-dependencies ${project.build.directory}/lib false false runtime org.springframework.boot spring-boot-maven-plugin ZIP nothing nothing

 

步骤二:.部署服务

将lib包脱离后的jar包是不可以直接通过java -jar xxx.jar的方式启动的,因为该jar包已经没有依赖包,没法去执行代码里面依赖的各种包的环境,

需要在启动的时候将lib包的路径也一并配置上。

首先,将lib包和jar文件一并放到服务器的某个目录下,然后通过命令启动:

nohup java -Dloader.path="lib/" -jar luan-account-web.jar &

 注意:-Dloader.path 配置的就是打包后的整个lib文件夹上传到服务器的目录下所指的路径,通常lib不会经常改动,所以在第一次部署的时候,我们将lib包部署到服务器之后就可以不用动了,后期如果有新的依赖包,只需要将新的依赖包再单独上传到服务器的lib包里面就好了,然后改动业务的代码后,每次只需要将最新打包的服务jar包发布部署就好。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有